package com.sec.samsung.android.app.baymax.view.activity;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.sec.samsung.android.app.baymax.R;
import com.sec.samsung.android.app.baymax.controll.BaymaxRequestManager;
import com.sec.samsung.android.app.baymax.controll.IRequestListener;
import com.sec.samsung.android.app.baymax.model.user.Account;
import com.sec.samsung.android.app.baymax.model.user.UserList;
import com.sec.samsung.android.app.baymax.utils.BaymaxConstant;
import com.sec.samsung.android.app.baymax.utils.BaymaxUtils;
import com.sec.samsung.android.app.baymax.utils.SharePrefUtils;
import com.sec.samsung.android.app.baymax.utils.StringUtility;
import com.sec.samsung.android.app.baymax.utils.TimeUtility;

public class ProfileActivity extends Activity implements OnClickListener {
    //=======================Constant Define===============
    private static final int REQUEST_CODE_CAMERA = 1001;
    private static final int REQUEST_CODE_GALLERY = 1002;
    private static final int CROP_FROM_CAMERA = 1003;
    private static final int REQUEST_CODE_HISTORY = 1004;
    //=======================Class Define==================
    //=======================Control Define================
    private Button mBtnBack;
    private ImageView mBtnUserAvatar;
    private EditText mUserName;
    private ImageView mImgGenderMan;
    private ImageView mImgGenderWoman;
    private DatePicker mDatePicker;
    private TextView mBtnNext;
    private TextView mBtnHistory;
    private ScrollView mScrollView;
    private LinearLayout mLinearOptions;
    //=======================Variable Define===============
    private Uri mCapturedImageURI;
    private String mUserImageStr;
    private String gender = BaymaxConstant.UNKNOWN;
    private int mNextType = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_profile);

        initLayout();
    }

    private void initLayout() {
        mScrollView = (ScrollView) findViewById(R.id.scroll_profile);
        mLinearOptions = (LinearLayout) findViewById(R.id.layout_profile_options);
        mBtnBack = (Button) findViewById(R.id.btn_back);
        mBtnUserAvatar = (ImageView) findViewById(R.id.img_user_avatar);
        mUserName = (EditText) findViewById(R.id.txt_user_name);
        mImgGenderMan = (ImageView) findViewById(R.id.gender_man);
        mImgGenderWoman = (ImageView) findViewById(R.id.gender_woman);
        mDatePicker = (DatePicker) findViewById(R.id.birthday_time_picker);
        mBtnNext = (TextView) findViewById(R.id.button_next);
        mBtnHistory = (TextView) findViewById(R.id.button_history);

        mBtnBack.setOnClickListener(this);
        mBtnUserAvatar.setOnClickListener(this);
        mBtnNext.setOnClickListener(this);
        mImgGenderMan.setOnClickListener(this);
        mImgGenderWoman.setOnClickListener(this);
        mBtnHistory.setOnClickListener(this);
        UserList userList = BaymaxUtils.getUserList(this);
        if (userList == null || userList.userList == null)
            mBtnHistory.setEnabled(false);
        else
            mBtnHistory.setEnabled(true);

    }

    @Override
    protected void onResume() {
        super.onResume();

        initLayout();
        mNextType = 0;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btn_back:
            break;
        case R.id.img_user_avatar:
            showDialogChooseImage();
            break;
        case R.id.button_next:
            onClickButtonNext();
            break;
        case R.id.gender_man:
            gender = BaymaxConstant.MALE;
            mImgGenderMan.setBackgroundResource(R.drawable.s_health_profilesetting_male_l_icon_nor);
            mImgGenderWoman.setBackgroundResource(R.drawable.s_health_profilesetting_female_l_icon_dim);
            break;
        case R.id.gender_woman:
            gender = BaymaxConstant.FEMALE;
            mImgGenderMan.setBackgroundResource(R.drawable.s_health_profilesetting_male_l_icon_dim);
            mImgGenderWoman.setBackgroundResource(R.drawable.s_health_profilesetting_female_l_icon_nor);
            break;
        case R.id.button_history:
            onClickHistory();
            break;
        default:
            break;
        }
    }

    private void onClickHistory() {
        Intent intent = new Intent(this, HistoryActivity.class);
        startActivityForResult(intent, REQUEST_CODE_HISTORY);
    }

    private void onClickButtonNext() {
        if (mUserName.getText().equals("")) {
            mUserName.setError(getString(R.string.name));
            showToast(getString(R.string.user_cannot_empty));
            return;
        }
        if (StringUtility.isEmpty(mUserName)) {
            mUserName.setError(getString(R.string.name));
            showToast(getString(R.string.user_cannot_empty));
            return;
        }
        if (gender == BaymaxConstant.UNKNOWN) {
            showToast(getString(R.string.choose_your_gender));
            return;
        }
        long currentTime = System.currentTimeMillis();
        long birthDayTime = getDateFromDatePicket(mDatePicker).getTime();
        if (birthDayTime >= currentTime) {
            showToast(getString(R.string.date_time_not_correct));
            return;
        }

        if (mNextType == 0 && !isViewVisible(mLinearOptions)) {
            mNextType++;
            mScrollView.post(new Runnable() {

                @Override
                public void run() {
                    mScrollView.smoothScrollTo(0, mLinearOptions.getBottom());
                }
            });
            return;
        }

        final Account account = new Account();
        String birthday = TimeUtility.formatDateToString(getDateFromDatePicket(mDatePicker));
        account.setBirthday(birthday);
        account.setGender(gender);
        account.setName(mUserName.getText().toString());
        account.setAvatarData(mUserImageStr);

        Gson gson = new GsonBuilder().serializeNulls().create();
        String userListJSON = gson.toJson(account);
        JSONObject params = null;
        try {
            params = new JSONObject(userListJSON);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        BaymaxRequestManager.getInstance(this).requestToPostUserInfo(account, new IRequestListener() {

            @Override
            public void onResponse(String response) {
                Log.d("KieuThang", "onResponse");
                savingUserData(account);

                Intent intent = new Intent(ProfileActivity.this, BodyPartChooser.class);
                Gson gson = new GsonBuilder().serializeNulls().create();
                String userListJSON = gson.toJson(account);
                intent.putExtra("user_data", userListJSON);
                startActivity(intent);
            }

            @Override
            public void onErrorResponse(String errorMessage) {
                Log.d("KieuThang", "onErrorResponse");
            }
        }, this);
        
    }

    private boolean isViewVisible(View view) {
        Rect scrollBounds = new Rect();
        mScrollView.getDrawingRect(scrollBounds);

        float top = view.getY();
        float bottom = top + view.getHeight();

        if (scrollBounds.top < top && scrollBounds.bottom > bottom) {
            return true;
        } else {
            return false;
        }
    }

    private void savingUserData(Account account) {
        UserList userList = BaymaxUtils.getUserList(this);
        if (userList == null) {
            userList = new UserList();
            userList.userList = new ArrayList<Account>();
        }
        boolean isCheckExistUser = false;
        for (int i = 0; i < userList.userList.size(); i++) {
            if (account.getName().equals(userList.userList.get(i).getName())) {
                userList.userList.get(i).setBirthday(account.getBirthday());
                userList.userList.get(i).setGender(account.getGender());
                userList.userList.get(i).setName(account.getName());
                userList.userList.get(i).setAvatarData(account.getAvatarData());
                isCheckExistUser = true;
            }
        }
        if (!isCheckExistUser) {
            userList.userList.add(account);
        }
        Gson gson = new GsonBuilder().serializeNulls().create();
        String userListJSON = gson.toJson(userList);
        SharePrefUtils.putStringValue(this, BaymaxConstant.KEY_USER_LIST_DATA, userListJSON);
        Log.d("KieuThang", "userJson:" + userListJSON);
    }

    public static java.util.Date getDateFromDatePicket(DatePicker datePicker) {
        int day = datePicker.getDayOfMonth();
        int month = datePicker.getMonth();
        int year = datePicker.getYear();

        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, day);

        return calendar.getTime();
    }

    private void showDialogChooseImage() {
        final Dialog dialog = new Dialog(this);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        LayoutInflater inflater = (LayoutInflater) getLayoutInflater();
        View dialog_view = inflater.inflate(R.layout.dialog_choose_picture, null);
        Button btnTakeAPicture = (Button) dialog_view.findViewById(R.id.btn_take_picture);
        btnTakeAPicture.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // when user click camera to get image
                try {
                    String fileName = "cover" + Calendar.getInstance().getTimeInMillis() + ".jpg";
                    ContentValues values = new ContentValues();
                    values.put(MediaStore.Images.Media.TITLE, fileName);
                    mCapturedImageURI = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
                    startActivityForResult(intent, REQUEST_CODE_CAMERA);
                } catch (Exception e) {
                    Log.e("KieuThang", "exception:" + e.getMessage());
                }
                dialog.dismiss();

            }
        });
        Button btnChooseFromLibrary = (Button) dialog_view.findViewById(R.id.btn_choose_from_library);
        btnChooseFromLibrary.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // when user click gallery to get image
                Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(galleryIntent, REQUEST_CODE_GALLERY);
                dialog.dismiss();
            }
        });
        Button btnCancel = (Button) dialog_view.findViewById(R.id.btn_choose_picture_cancel);
        btnCancel.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        dialog.setContentView(dialog_view);
        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
        Window window = dialog.getWindow();
        lp.copyFrom(window.getAttributes());
        // This makes the dialog take up the full width
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.MATCH_PARENT;
        window.setAttributes(lp);

        dialog.show();
    }

    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        Log.d("KieuThang", "requestCode:" + requestCode + ", resultCode:" + resultCode + ", data:" + data);
        switch (requestCode) {
        case REQUEST_CODE_CAMERA:
            if (resultCode == RESULT_OK) {
                if (mCapturedImageURI == null) {
                    Log.d("KieuThang", "mCapturedImageURI is null");
                    if (data == null || data.getExtras() == null)
                        return;
                    Bitmap photo = (Bitmap) data.getExtras().get("data");
                    if (photo == null)
                        return;
                    else {
                        cropImageFromUri(data.getData());
                        return;
                    }
                }

                String[] projection = { MediaStore.Images.Media.DATA };
                Cursor cursor = getContentResolver().query(mCapturedImageURI, projection, null, null, null);
                if (cursor == null) {
                    Log.d("KieuThang", "cursor is null");
                    return;
                }
                int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();

                // THIS IS WHAT YOU WANT!
                String capturedImageFilePath = cursor.getString(column_index_data);
                File file = new File(capturedImageFilePath);
                if (file.exists()) {
                    Uri fileUri = Uri.fromFile(file);
                    cropImageFromUri(fileUri);
                }
            }
            break;
        case REQUEST_CODE_GALLERY:
            if (resultCode == RESULT_OK) {
                Log.d("KieuThang", "data=" + data);
                if (data == null) {
                    Log.d("KieuThang", "Opps!Can not get data from gallery.");
                    return;
                }

                Uri uri = data.getData();
                String[] filePathColumn = { MediaStore.Images.Media.DATA };
                Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
                cursor.moveToFirst();
                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String imagePath = cursor.getString(columnIndex);
                cursor.close();

                File file = new File(imagePath);
                Uri fileUri = null;
                if (file.exists()) {
                    fileUri = Uri.fromFile(file);
                    cropImageFromUri(fileUri);
                } else {
                    Log.d("KieuThang", "file don't exist !");
                }
            }
            break;
        case CROP_FROM_CAMERA:
            if (resultCode == RESULT_OK) {
                Bundle extras = data.getExtras();
                if (extras != null) {
                    Bitmap photo = extras.getParcelable("data");
                    mUserImageStr = convertUserImageToString(photo);
                    mBtnUserAvatar.setImageBitmap(photo);
                }
            }
            break;
        case REQUEST_CODE_HISTORY:
            if (data == null)
                return;
            Bundle extras = data.getExtras();
            if (extras != null) {
                String userJson = extras.getString("return_data");
                Log.d("KieuThang", "userJson:" + userJson);
                if (userJson == null)
                    return;
                Gson gson = new GsonBuilder().serializeNulls().create();
                Account user = gson.fromJson(userJson, Account.class);
                if (user == null)
                    return;
                updateLayout(user);
            }
            break;
        default:
            return;
        }
    }

    @SuppressWarnings("deprecation")
    private void updateLayout(Account account) {
        mUserName.setText(account.getName());
        if (account.getGender() == BaymaxConstant.MALE) {
            gender = BaymaxConstant.MALE;
            mImgGenderMan.setBackgroundResource(R.drawable.s_health_profilesetting_male_l_icon_nor);
            mImgGenderWoman.setBackgroundResource(R.drawable.s_health_profilesetting_female_l_icon_dim);
        } else if (account.getGender() == BaymaxConstant.FEMALE) {
            gender = BaymaxConstant.FEMALE;
            mImgGenderMan.setBackgroundResource(R.drawable.s_health_profilesetting_male_l_icon_dim);
            mImgGenderWoman.setBackgroundResource(R.drawable.s_health_profilesetting_female_l_icon_nor);
        }
        if (account.getAvatarData() == null) {
            mBtnUserAvatar.setBackgroundResource(R.drawable.btn_selector_user_avatar);
            mBtnUserAvatar.setImageBitmap(null);
        }
        Bitmap bitmap = BaymaxUtils.convertBitmapFromString(account.getAvatarData());
        if (bitmap != null) {
            mBtnUserAvatar.setImageBitmap(bitmap);
        }
        else {
            mBtnUserAvatar.setBackgroundResource(R.drawable.btn_selector_user_avatar);
            mBtnUserAvatar.setImageBitmap(null);
        }

        Date date = TimeUtility.convertStringToDate(account.getBirthday());
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(date.getTime());
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        mDatePicker.updateDate(year, month, day);
    }

    private String convertUserImageToString(Bitmap photo) {
        BitmapFactory.Options options = new BitmapFactory.Options();

        options.inSampleSize = 1;
        options.inPurgeable = true;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        photo.compress(Bitmap.CompressFormat.PNG, 100, baos);
        // bitmap object
        byte byteImage_photo[] = baos.toByteArray();
        String encodedImage = Base64.encodeToString(byteImage_photo, Base64.DEFAULT);
        try {
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return encodedImage;
    }

    private void cropImageFromUri(Uri uri) {
        Intent intent = new Intent(BaymaxConstant.CROP_INTENT);

        intent.setType("image/*");

        List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, 0);

        int size = list.size();
        if (size == 0) {
            showToast("Can not crop image");
            return;
        } else {
            intent.setData(uri);
            intent.putExtra("outputX", 512);
            intent.putExtra("outputY", 512);
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 1);
            intent.putExtra("scale", true);
            intent.putExtra("return-data", true);
            if (size >= 1) {
                Intent i = new Intent(intent);
                ResolveInfo res = list.get(0);
                i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
                startActivityForResult(i, CROP_FROM_CAMERA);
            }
        }
    }

    private void showToast(String string) {
        Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
    }
}
